package cc.risingsun.wing.test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Set;

import org.junit.Test;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.util.TraceClassVisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cc.risingsun.wing.core.WingEntityClassVisitor;
import cc.risingsun.wing.dai.entity.WingEntityBean;
import cc.risingsun.wing.ds.DataStruct;

/**
 * 
 * @author iron.yin@gmail.com
 * @since 2012-6-21
 */
public class WingClassLoaderTestSuite {

	@Test
	public void loadTest() throws ClassNotFoundException,
			InstantiationException, IllegalAccessException {
		WingClassLoader loader = new WingClassLoader();
		Class<?> clazz = loader.loadClass(Bean.class.getName());
		WingEntityBean wb = (WingEntityBean) clazz.newInstance();
		wb.setValue("name", "小明");
		wb.setValue("age", 12);
		wb.setValue("date", new Date());
		System.out.println(wb.getFields().size());
	}

}

class WingClassLoader extends ClassLoader {

	private static final Logger logger = LoggerFactory
			.getLogger(WingClassLoader.class);

	private Set<String> classes;

	public WingClassLoader() {
		classes = DataStruct.hashSet();
		classes.add(Bean.class.getName());
	}

	@Override
	protected synchronized Class<?> loadClass(String name, boolean resolve)
			throws ClassNotFoundException {
		if (classes.contains(name)) {
			String resource = name.replace('.', '/') + ".class";
			InputStream is = getResourceAsStream(resource);
			byte[] bytes = null;
			try {
				ClassReader cr = new ClassReader(is);
				ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
				ClassVisitor cv = new WingEntityClassVisitor(cw);
				cr.accept(cv, 0);
				bytes = cw.toByteArray();
				cr = new ClassReader(bytes);
				TraceClassVisitor tcv = new TraceClassVisitor(new PrintWriter(
						System.out));
				cr.accept(tcv, 0);
				File file = new File(
						"C:\\Users\\Administrator\\Desktop\\Bean.class");
				FileOutputStream fout = new FileOutputStream(file);
				fout.write(bytes);
				fout.close();
			} catch (IOException e) {
				logger.error(e.getMessage(), e);
			}
			return defineClass(name, bytes, 0, bytes.length);
		}
		return super.loadClass(name, resolve);
	}

}
